package com.yx.elastic.elasticcm.client;

import com.yx.elastic.elasticcm.util.StringUtils;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * Created by chenzp on 18-7-27.
 */
@Component
public class MClientManager {


    private static Logger logger = LoggerFactory.getLogger(MClientManager.class);

    //默认ip地址
    public final static String HOST = "localhost";
    //默认http类型
    public final static String SCHEME = "http";
    //默认端口号
    public final static Integer PORT = 9200;

    private static final int CONNECT_TIME_OUT = 1000;
    private static final int SOCKET_TIME_OUT = 30000;
    private static final int CONNECTION_REQUEST_TIME_OUT = 500;

    private static final int MAX_CONNECT_NUM = 100;
    private static final int MAX_CONNECT_PER_ROUTE = 100;



    private static HttpHost HTTP_HOST=null;

    private static boolean uniqueConnectTimeConfig = false;
    private static boolean uniqueConnectNumConfig = true;
    private static RestClientBuilder builder;

    private static RestClient restClient;

    private static RestHighLevelClient restHighLevelClient;

    @Autowired
    private  ElasticConfig elasticConfig;


    public MClientManager() {
    }

    private void init() {
        String host = HOST;

        if (StringUtils.isNotNullAndEmpty(elasticConfig.httphost)) {
            host = elasticConfig.httphost;
        }

        String se = SCHEME;

        if (StringUtils.isNotNullAndEmpty(elasticConfig.scheme)) {
            se = elasticConfig.scheme;
        }

        int pt = PORT;
        if (elasticConfig.port != null) {
            pt = elasticConfig.port;
        }

        if(HTTP_HOST==null){
            HTTP_HOST=new HttpHost(host,pt,se);
        }
        builder = RestClient.builder(HTTP_HOST);
        if(uniqueConnectTimeConfig){
            setConnectTimeOutConfig();
        }
        if(uniqueConnectNumConfig){
            setMutiConnectConfig();
        }
        restClient = builder.build();
        restHighLevelClient = new RestHighLevelClient(builder);
    }


    public RestClient getClient(){
        if (restClient == null) {
            synchronized (MClientManager.class) {
                if (restClient == null) {
                    init();
                    return restClient;
                }
            }
        }
        return restClient;
    }


    public  RestHighLevelClient getHighLevelClient() {
        if (restHighLevelClient == null) {
            synchronized (MClientManager.class) {
                if (restHighLevelClient == null) {
                    init();
                    return restHighLevelClient;
                }
            }
        }
        return restHighLevelClient;
    }


    /**
     *     主要关于异步httpclient的连接延时配置
     */

    public static void setConnectTimeOutConfig(){
        builder.setRequestConfigCallback(requestConfigBuilder -> {
            requestConfigBuilder.setConnectTimeout(CONNECT_TIME_OUT);
            requestConfigBuilder.setSocketTimeout(SOCKET_TIME_OUT);
            requestConfigBuilder.setConnectionRequestTimeout(CONNECTION_REQUEST_TIME_OUT);
            return requestConfigBuilder;
        });
    }
    /**
     *    主要关于异步httpclient的连接数配置
     */
    public static void setMutiConnectConfig(){
        builder.setHttpClientConfigCallback(httpClientBuilder -> {
            httpClientBuilder.setMaxConnTotal(MAX_CONNECT_NUM);
            httpClientBuilder.setMaxConnPerRoute(MAX_CONNECT_PER_ROUTE);
            return httpClientBuilder;
        });
    }




    /**
     * 关闭客户端
     */
    public  void close() {
        if (restClient != null) {
            try {
                restClient.close();
                restClient = null;
            } catch (IOException e) {
                logger.error("关闭elasticsearch客户端异常" + e.getMessage());
                e.printStackTrace();
            }
        }

        if (restHighLevelClient != null) {
            try {
                restHighLevelClient.close();
            } catch (IOException e) {
                logger.error("关闭elasticsearch客户端异常" + e.getMessage());
                e.printStackTrace();
            }
        }

    }

}
